package com.ly.mpayment.rest.up.yunshan;

import com.alibaba.fastjson.JSONObject;
import com.ly.mpayment.core.secuity.MD5;
import com.ly.mpayment.core.util.*;
import com.ly.mpayment.persist.entity.UpOrder;
import com.ly.mpayment.persist.entity.UpShopInfo;
import com.ly.mpayment.persist.service.downrechargeflow.IDownRechargeFlowService;
import com.ly.mpayment.persist.service.downshopinfo.IDownShopInfoService;
import com.ly.mpayment.persist.service.uporder.IUporderService;
import com.ly.mpayment.persist.service.upshopinfo.IUpShopInfoService;
import com.ly.mpayment.rest.recharge.RechargeRest;
import org.apache.log4j.Logger;
import org.mortbay.util.MultiMap;
import org.mortbay.util.UrlEncoded;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

@Component
@Path("yunshan")
public class YunShanRest {

    Logger logger = Logger.getLogger(YunShanRest.class);


    @Autowired
    IUporderService upOrderService;

    @Autowired
    IDownRechargeFlowService flowService;

    @Autowired
    IDownShopInfoService shopService;

    @Autowired
    IUpShopInfoService upShopInfoService;

    /**
     */
    @Path("callBack")
    @POST
    public synchronized String callBack(@RequestBody String body){
        logger.info("yunshan_back:"+body);
        MultiMap multimap = parceString(body);
        if(!StringUtils.isBlank(multimap.getString("reqid"))){
            //corpid	32	Y	账号
            //reqid	50	Y	唯一单号
            //orderid	20	Y	平台交易单号
            //finish	20	Y	实到金额/流量
            //price	15	Y	实付金额
            //status	1	Y	订单状态：1-成功/2-失败
            //refid	80	N	参考凭证（运营商订单号/卡号）
            //sign	32	Y	签名

            //Md5(corpid + reqid + orderid + finish + price + status + refid + key)
            UpOrder order = upOrderService.findById(multimap.getString("reqid"));
            if (order != null && multimap.getString("status").equals("1") && order.getStatus() == Config.status[0]) {
                order.setRemark(multimap.getString("refid") );
                RechargeRest.successUpOrder.add(order);
                return "SUCCESS";
            }else if(order != null && order.getStatus() == Config.status[0] && multimap.getString("status").equals("2")){
                order.setRemark(multimap.getString("status"));
                RechargeRest.failtUpOrder.add(order);
                return "SUCCESS";
            }else{
                logger.info("yunshan_not_found_order:" + multimap.getString("reqid") +","+ (order == null ? " order is null" : order.getUpphonenum() ));
            }
        }
        return "FAIL";
    }

    private MultiMap parceString(String str){
        MultiMap map = new MultiMap();
        UrlEncoded.decodeTo(str, map, "utf-8");
        return map;
    }

    /**
     * 签名
     * @param jsonObject
     * @param key
     * @return
     */
    private String sign(JSONObject jsonObject, String key,String keyValue){
        //将所有请求的参数放进TreeMap，TreeMap默认按照key升序排列
        Map<String, String> map = new TreeMap<>();
        for(String s : jsonObject.keySet()){
            map.put(s,jsonObject.getString(s));
        }

        StringBuilder sb = new StringBuilder();
        //循环拼接所有value
        for (String k : map.keySet()) {
            sb.append(k);
            sb.append("=");
            sb.append(map.get(k));
            sb.append("&");
        }
        //最后拼接上秘钥
        sb.append(key);
        sb.append("=");
        sb.append(keyValue);
        logger.info("签名前：" + sb.toString());
        return MD5.md5(sb.toString());
    }

    /**
     * corpid	32	Y	账号
     * reqid	50	Y	唯一流水号
     * ts	14	Y	时间戳，格式为：yyyyMMddHHmmss
     * productid	10	Y	产品编码（由我方提供）
     * number	20	Y	充值号码
     * returl	128	Y	回调地址
     * sign	32	Y	签名
     * @return
     */
    public void commitOrder(UpOrder order, UpShopInfo shop) {
        UpOrder product = this.upOrderService.findOrderProduct(order.getUporderuuid());
        if (product != null) {
            JSONObject data = new JSONObject();
            data.put("corpid",shop.getAppId());
            data.put("reqid",order.getUporderuuid());
            data.put("ts",new DateUtils().toTimeStamp());
            data.put("productid",product.getUpShopPro().getProductCode());
            data.put("number",order.getUpphonenum());
            data.put("returl",shop.getOrderCallAddress());
            //签名格式：	Md5(corpid + reqid + ts + productid + number + returl + key)
            data.put("sign",MD5.md5(shop.getAppId()+order.getUporderuuid()+data.getString("ts")+product.getUpShopPro().getProductCode()+
                    order.getUpphonenum()+shop.getOrderCallAddress()+shop.getUpkey()));
            String res = HttpClient.postUrl(shop.getOrderCommitAddress(),StringSort.jsonToString(data));
            //{"code":200,"data":{"orderid":"202001221607520007","price":1.000,"reqid":"5a4ca477352a3f1e3"},"msg":"","result":"success","serviceTime":"2020-05-20 16:07:52"}
            //{"code":10001,"result":"error","msg":"参数错误","data":null,"serviceTime":"2020-05-20 17:14:49"}

            logger.info("commityunshan_result:" + data +",phone:"+order.getUpphonenum()+",res:"+res);
            if (!StringUtils.isBlank(res)) {
                JSONObject result = JSONObject.parseObject(res);
                if(result.containsKey("code") && result.getString("code").equals("200")){
                    upOrderService.updateUpOrderMsg(order, result.getJSONObject("data").getString("orderid"),result.getString("result"));
                }else if (result.containsKey("code") && codesError.contains(result.getString("code"))) {
                    order.setRemark(result.containsKey("msg") ?	result.getString("msg") : Config.orderFailA);
                    RechargeRest.failtUpOrder.add(order);
                }
            } else {
                upOrderService.commitFailt(order,  Config.commitFailt);
                logger.info("commityunshan_error" + order.getUpphonenum());
            }
        }
    }

    /**
     * 10001	参数错误
     * 10002	签名错误
     * 10003	IP地址受限（与绑定地址不一致）
     * 10004	接口关闭
     * 10005	账号状态异常
     * 10011	号码黑名单
     * 10007	无此商品
     * 10008	商品下架
     * 10009	余额不足
     */
    private static Set<String> codesError = new HashSet<String>(){{
        add("10001");
        add("10002");
        add("10003");
        add("10004");
        add("10005");
        add("10011");
        add("10007");
        add("10008");
        add("10009");
    }};


    /**
     * corpid	32	Y	代理账号
     * reqid	50	Y	代理唯一流水号
     * sign	32	Y	签名数据
     * Md5(corpid + reqid + key)
     * {"code":200,"result":"success","msg":"","data":{"orderid":"154543541545","status":3,"price":1.000,"refid":" "},"serviceTime":"2020-05-20 17:25:41"}
     * {"code":10010,"result":"error","msg":"订单不存在","data":null,"serviceTime":"2020-05-20 17:29:24"}
     * @return
     */

    public void queryOrder(UpOrder upOrder, UpShopInfo shopInfo) {
        if(upOrder != null ){
            UpOrder product = upOrderService.findOrderProduct(upOrder.getUporderuuid());
            if (product != null) {
                JSONObject data = new JSONObject();
                data.put("corpid",shopInfo.getAppId());
                data.put("reqid",upOrder.getUporderuuid());
                data.put("sign",MD5.md5(shopInfo.getAppId()+upOrder.getUporderuuid()+shopInfo.getUpkey()));
                String res = HttpClient.postUrl(shopInfo.getOrderStatusAddress(),StringSort.jsonToString(data));
                logger.info("queryyunshan:"+res+"data:"+data+",phone:"+upOrder.getUpphonenum());
                if(res != null){
                    JSONObject result = JSONObject.parseObject(res);
                    if(result.containsKey("code")){
                        //订单状态：3-成功，2-失败，其他-处理中(订单最终充值状态以此为准)
                        if( result.getString("code").equals("200") && result.getJSONObject("data").getString("status").equals("3") ){
                            UpOrder order = upOrderService.findById(upOrder.getUporderuuid());
                            if(order != null && order != null && order.getStatus() == Config.status[0]){
                                order.setRemark(result.getJSONObject("data").containsKey("refid") ? result.getJSONObject("data").getString("refid") :
                                        result.getString("result"));
                                RechargeRest.successUpOrder.add(order);
                            }
                        }else if( result.getString("code").equals("200") && result.getJSONObject("data").getString("status").equals("2") ){
                            UpOrder order = upOrderService.findById(upOrder.getUporderuuid());
                            if( order != null && order.getStatus() == Config.status[0]){
                                order.setRemark(result.containsKey("msg") ?	result.getString("msg") : Config.orderFailA);
                                RechargeRest.failtUpOrder.add(order);
                            }
                        }
                    }else{
                        logger.debug("queryyunshan查询失败:"+upOrder.getUpphonenum());
                    }
                }else{
                    logger.info("queryyunshan order failt:"+upOrder.getUpphonenum());
                }
            }
        }else{
            logger.info("queryyunshan order failt:"+upOrder.getUpphonenum());
        }
    }
}
